import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core';
import {JsonEditorComponent, JsonEditorOptions} from 'ang-jsoneditor';
import {EntityRef} from '../../entity/entity-ref';
import {EntityJsonPipe} from '../../pipe/entity-json.pipe';
import {DocService} from '../../service/doc.service';
import {InvokeUtils} from '../../utils/invoke-utils';
import {InvokeDataRest} from '../../entity/invoke-data-rest';


@Component({
    selector: 'app-invoke-request-body',
    templateUrl: './invoke-request-body.component.html',
    styleUrls: ['./invoke-request-body.component.css']
})
export class InvokeRequestBodyComponent {
    private _data: InvokeDataRest;

    rawData: any;

    @Output() dataChange = new EventEmitter<InvokeDataRest>();

    @Input()
    requestBodys: EntityRef[];

    requestBodyTypes = ['form-data', 'x-www-form-urlencoded', 'raw'];

    contentTypes = ['application/json', 'text', 'text/plain', 'application/javascript', 'application/xml', 'text/xml', 'text/html'];

    jsonEditorOptions: JsonEditorOptions;

    @ViewChild('jsonEditor') editor: JsonEditorComponent;

    constructor(private docService: DocService) {
        this.jsonEditorOptions = new JsonEditorOptions();
        this.jsonEditorOptions.indentation = 4;
        this.jsonEditorOptions.mode = 'code';
        this.jsonEditorOptions.onChange = this.rawDataChange.bind(this);
        this.jsonEditorOptions.statusBar = false;
    }

    @Input()
    set data(data: InvokeDataRest) {
        this._data = data;
        this.updateRawJsonData();
    }

    get data(): InvokeDataRest {
        return this._data;
    }

    rawDataChange(): void {
        this._data.requestBody.rawData = this.editor.getText();
        this.dataChange.emit(this._data);
    }

    get requestBodyType() {
        return this._data.requestBody.rawDataType;
    }

    set requestBodyType(requestBodyType: string) {
        this._data.requestBody.rawDataType = requestBodyType;

        if (requestBodyType === 'x-www-form-urlencoded' || requestBodyType === 'form-data') {
            InvokeUtils.setContentType(this._data, 'application/x-www-form-urlencoded');
            this.dataChange.emit(this._data);
        } else if (requestBodyType === 'raw') {
            InvokeUtils.setContentType(this._data, 'application/json');
            this.dataChange.emit(this._data);

            // 切换回来的时候，需要重新渲染编辑器
            this.updateRawJsonData();
        }
    }

    onRawDataTypeChange(values: string[]) {
        if (!values || values.length === 0) {
            return;
        }
        InvokeUtils.setContentType(this._data, values[0]);
        this.dataChange.emit(this._data);
    }

    getContentType(): string {
        return InvokeUtils.getContentType(this._data.headers);
    }

    private updateRawJsonData() {
        let rawData = this.data.requestBody.rawData;
        if (!rawData) {
            rawData = '{}';
        }
        if (this.data.id) {
            // demo数据，不需要处理
            this.rawData = JSON.parse(rawData);
            return;
        }

        try {
            if (this.requestBodys && this.requestBodys[0]) {
                const entityJsonPipe = new EntityJsonPipe(this.docService);
                rawData = this.data.requestBody.rawData = entityJsonPipe.transform(this.requestBodys[0], false);
                this.rawData = JSON.parse(rawData);
            } else {
                this.rawData = JSON.parse(rawData);
            }
        } catch (e) {
            console.error('响应体JSON结构异常：' + rawData);
            this.rawData = {};
        }

    }
}
